<?php

/**
 * Name: 签到请求验证类
 * User: Silent
 * Date: 2025-11-07
 * Time: 17:00:00
 */

namespace App\Http\Requests\Checkin;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Contracts\Validation\Validator;

class CheckinRequest extends FormRequest
{
    /**
     * 判断用户是否有权限进行此请求
     */
    public function authorize()
    {
        return true;
    }

    /**
     * 数据预处理 - 在验证前执行
     */
    protected function prepareForValidation()
    {
        // 布尔字段列表
        $booleanFields = [
            'has_injury', 'is_tired', 'after_drinking', 'is_sleepy', 'over_played',
            'absent_over_10_days', 'is_new_or_transferred', 'has_urgent_family',
            'had_trouble_on_way', 'has_social_dispute', 'drink_alcohol'
        ];

        $data = [];
        foreach ($booleanFields as $field) {
            if ($this->has($field)) {
                $value = $this->input($field);
                // 将任何形式的布尔值统一转换为 0 或 1
                if ($value === 'true' || $value === true || $value === 1 || $value === '1') {
                    $data[$field] = 1;
                } else {
                    $data[$field] = 0;
                }
            }
        }

        $this->merge($data);
    }

    /**
     * 获取验证规则
     */
    public function rules()
    {
        return [
            // 班前危险排查（10项）- 经过预处理后，这里只需验证 0 或 1
            'has_injury' => 'required|in:0,1',
            'is_tired' => 'required|in:0,1',
            'after_drinking' => 'required|in:0,1',
            'is_sleepy' => 'required|in:0,1',
            'over_played' => 'required|in:0,1',
            'absent_over_10_days' => 'required|in:0,1',
            'is_new_or_transferred' => 'required|in:0,1',
            'has_urgent_family' => 'required|in:0,1',
            'had_trouble_on_way' => 'required|in:0,1',
            'has_social_dispute' => 'required|in:0,1',
            'team_name' => 'required|string|max:255',

            // 仪器测定（3项）
            'drink_alcohol' => 'required|in:0,1',
            'blood_pressure_systolic' => 'required|integer|min:1|max:999',
            'blood_pressure_diastolic' => 'required|integer|min:1|max:999',
            'temperature' => 'required|numeric|min:1.0|max:99.9',

            // 备注（可选）
            'remark' => 'nullable|string|max:500',
        ];
    }

    /**
     * 获取验证错误消息
     */
    public function messages()
    {
        return [
            // 班前危险排查验证消息
            'has_injury.required' => '请选择是否有伤病',
            'has_injury.boolean' => '伤病状态格式错误',
            'is_tired.required' => '请选择是否连续工作劳累',
            'is_tired.boolean' => '疲劳状态格式错误',
            'after_drinking.required' => '请选择是否酒后上班',
            'after_drinking.boolean' => '饮酒状态格式错误',
            'is_sleepy.required' => '请选择是否失眠困乏',
            'is_sleepy.boolean' => '失眠状态格式错误',
            'over_played.required' => '请选择是否玩乐过度',
            'over_played.boolean' => '玩乐状态格式错误',
            'absent_over_10_days.required' => '请选择离岗时间是否超过10天',
            'absent_over_10_days.boolean' => '离岗时间状态格式错误',
            'is_new_or_transferred.required' => '请选择是否新到岗或调岗',
            'is_new_or_transferred.boolean' => '新到岗状态格式错误',
            'has_urgent_family.required' => '请选择家庭是否有紧急事务',
            'has_urgent_family.boolean' => '家庭紧急事务状态格式错误',
            'had_trouble_on_way.required' => '请选择到岗途中是否遇到麻烦',
            'had_trouble_on_way.boolean' => '到岗途中状态格式错误',
            'has_social_dispute.required' => '请选择是否有严重社会纠葛',
            'has_social_dispute.boolean' => '社会纠葛状态格式错误',
            'team_name.required' => '请选择班组',
            'team_name.string' => '班组名称格式错误',
            'team_name.max' => '班组名称不能超过255个字符',

            // 仪器测定验证消息
            'drink_alcohol.required' => '请选择是否饮酒',
            'drink_alcohol.boolean' => '饮酒状态格式错误',
            'blood_pressure_systolic.required' => '请输入收缩压（高压）',
            'blood_pressure_systolic.integer' => '收缩压必须为整数',
            'blood_pressure_systolic.min' => '收缩压必须大于0',
            'blood_pressure_systolic.max' => '收缩压数值过大',
            'blood_pressure_diastolic.required' => '请输入舒张压（低压）',
            'blood_pressure_diastolic.integer' => '舒张压必须为整数',
            'blood_pressure_diastolic.min' => '舒张压必须大于0',
            'blood_pressure_diastolic.max' => '舒张压数值过大',
            'temperature.required' => '请输入体温',
            'temperature.numeric' => '体温必须为数字',
            'temperature.min' => '体温必须大于0℃',
            'temperature.max' => '体温数值过大',

            // 备注验证消息
            'remark.string' => '备注必须为文本格式',
            'remark.max' => '备注不能超过500个字符',
        ];
    }

    /**
     * 获取字段别名
     */
    public function attributes()
    {
        return [
            'has_injury' => '是否有伤病',
            'is_tired' => '是否连续工作劳累',
            'after_drinking' => '是否酒后上班',
            'is_sleepy' => '是否失眠困乏',
            'over_played' => '是否玩乐过度',
            'absent_over_10_days' => '离岗时间是否超过10天',
            'is_new_or_transferred' => '是否新到岗或调岗',
            'has_urgent_family' => '家庭是否有紧急事务',
            'had_trouble_on_way' => '到岗途中是否遇到麻烦',
            'has_social_dispute' => '是否有严重社会纠葛',
            'drink_alcohol' => '是否饮酒',
            'blood_pressure_systolic' => '收缩压',
            'blood_pressure_diastolic' => '舒张压',
            'temperature' => '体温',
            'remark' => '备注',
        ];
    }

    /**
     * 自定义验证逻辑
     */
    public function withValidator(Validator $validator)
    {
        $validator->after(function (Validator $validator) {
            // 只验证血压值的基本逻辑关系
            $systolic = $this->input('blood_pressure_systolic');
            $diastolic = $this->input('blood_pressure_diastolic');

            if ($systolic && $diastolic && $systolic <= $diastolic) {
                $validator->errors()->add('blood_pressure_systolic', '收缩压必须大于舒张压');
            }
        });
    }

    /**
     * 处理验证失败
     */
    protected function failedValidation(Validator $validator)
    {
        $errors = $validator->errors()->toArray();

        // 格式化错误消息
        $formattedErrors = [];
        foreach ($errors as $field => $messages) {
            $formattedErrors[$field] = $messages[0]; // 只取第一个错误消息
        }

        $response = response()->json([
            'code' => 422,
            'message' => '提交数据验证失败',
            'data' => null,
            'errors' => $formattedErrors
        ], 422);

        throw new HttpResponseException($response);
    }

    /**
     * 获取处理后的验证数据
     * 由于已经在 prepareForValidation 中处理过，这里直接返回验证后的数据
     */
    public function getProcessedData()
    {
        return $this->validated();
    }
}
